import cv2
import numpy as np

filename = r'C:\Users\Administrator\Desktop\chessboard.png'
filename2 = r'C:\Users\Administrator\Desktop\building.jpg'
img = cv2.imread(filename)
img = cv2.resize(img,(int(img.shape[1]/8),int(img.shape[0]/8)))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = cv2.imread(filename2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

#自己定义一个harris函数
class HarrisDetector(object):
    def _int_(self):
        self.maxStrength = 0.0 # 阈值计算的最大强度
        self.threshold = 0.01 # 计算得到的阈值（内部）
        self.nonMaxSize = 3  # 非极大值抑制的相邻像素的尺寸
        self.kernel = np.zeros((self.nonMaxSize, self.nonMaxSize), np.int8) # 非极大值抑制的核
        self.cornerStrength = None # 表示角点强度的32位浮点图像
        self.cornerTh = None   # 阈值化之后的32位浮点图像
        self.localMax = None  # 内部局部最大值

    def detect(self,image):
        self.cornerStrength = cv2.cornerHarris(image, 2, 3, 0.04)
        min_val, self.maxStrength, min_indx, max_indx = cv2.minMaxLoc(self.cornerStrength)
        dilated = cv2.dilate(self.cornerStrength, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)))
        self.localMax = cv2.compare(self.cornerStrength, dilated, cv2.CMP_EQ)

    def getCornerMap(self, qualityLevel):
        self.threshold = qualityLevel * self.maxStrength
        _, self.cornerTh = cv2.threshold(self.cornerStrength, self.threshold, 255, cv2.THRESH_BINARY)
        self.cornerTh = np.array(self.cornerTh)
        self.cornerMap = self.cornerTh.astype(np.uint8)
        result = self.cornerTh.astype(np.uint8)
        cv2.bitwise_and(self.cornerMap, self.localMax, self.cornerMap)
        cv2.bitwise_and(result, self.cornerMap, result)


    def getCornersMat(self, points, cornerMap):
        for i in range(cornerMap.shape[0]):
            for j in range(cornerMap.shape[1]):
                if cornerMap[i][j]:
                    points.append((j,i))

    def getCorners(self, points, qualityLevel):
        self.getCornerMap(qualityLevel)
        self.getCornersMat(points, self.cornerMap)
        return points

    def drawOnImage(self, image, points, color, radius, thickness):
        for i in points:
            cv2.circle(image, i, radius, color, thickness)

harris = HarrisDetector()
harris.detect(gray)
pts = []
pts = harris.getCorners(pts, 0.05)
harris.drawOnImage(img,pts,(0, 0, 255),3,2)
cv2.imshow("Harris_chessboard", img)

harris2 = HarrisDetector()
harris2.detect(gray2)
pts2 = []
pts2 = harris2.getCorners(pts2, 0.05)
harris2.drawOnImage(img2,pts2,(0, 0, 255),3,2)
cv2.imshow("Harris_building", img2)

cv2.waitKey(0)
cv2.destroyAllWindows()